﻿using System;
using System.IO;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.Logging;

namespace AChance.Func
{
    public static class FunLogs
    {
        private static ILogger _logger = new LoggerFactory().AddLog4Net().CreateLogger("AChance");
        public static string CurrentPath { get; } = FunContext.CurrentPath + "Logs\\";
        public static bool Init()
        {
            try
            {
                if (!Directory.Exists(CurrentPath))
                    Directory.CreateDirectory(CurrentPath);
                return true;
            }
            catch
            {
                return false;
            }
        }
        public static void Clear()
        {
            try
            {
                if (!Directory.Exists(CurrentPath))
                    return;
                DirectoryInfo logsPath = new DirectoryInfo(CurrentPath);
                foreach (FileInfo logsFile in logsPath.GetFiles())
                {
                    logsFile.Delete();
                }
            }
            catch { }
        }
        public static void ClearExpired()
        {
            try
            {
                if (!Directory.Exists(CurrentPath))
                    return;
                DirectoryInfo logsPath = new DirectoryInfo(CurrentPath);
                foreach (FileInfo logsFile in logsPath.GetFiles())
                {
                    if (logsFile.LastWriteTime > DateTime.Now.AddDays(-360))
                        continue;
                    logsFile.Delete();
                }
            }
            catch { }
        }

        #region Info
        public static void LogInfo(string info)
        {
            _logger.LogInformation(info);
        }
        public static void LogInfo(string info, string detail)
        {
            _logger.LogInformation($"{info} -- {detail}");
        }
        #endregion

        #region Warn
        public static void LogWarn(string warn)
        {
            _logger.LogWarning(warn);
        }
        public static void LogWarn(string warn, string detail)
        {
            _logger.LogWarning($"{warn} -- {detail}");
        }
        public static void LogWarnForTransExec(string transName, TimeSpan execTime, bool checkTimeout = false, double timeout = 3000)
        {
            if (!checkTimeout || execTime.TotalMilliseconds > timeout)
                _logger.LogWarning($"交易执行耗时({execTime.TotalMilliseconds.ToString()})毫秒 -- {transName}");
        }
        public static void LogWarnForSqlExec(string originalSql, TimeSpan execTime, bool checkTimeout = false, double timeout = 3000)
        {
            if (!checkTimeout || execTime.TotalMilliseconds > timeout)
                _logger.LogWarning($"Sql执行耗时({execTime.TotalMilliseconds.ToString()})毫秒\r\n   (原始Sql) {originalSql.Trim()}");
        }
        public static void LogWarnForSqlExec(CommandExecutedEventData eventData, string originalSql, TimeSpan execTime, bool checkTimeout = false, double timeout = 3000)
        {
            if (!checkTimeout || execTime.TotalMilliseconds > timeout)
                _logger.LogWarning($"Sql执行耗时({execTime.TotalMilliseconds.ToString()})毫秒\r\n   (含{eventData.Command.Parameters.Count}个参数) {eventData.Command.CommandText.Trim()}\r\n   (原始Sql) {originalSql.Trim()}");
        }
        public static void LogWarnForRestExec(string restUrl, TimeSpan execTime, bool checkTimeout = false, double timeout = 3000)
        {
            if (!checkTimeout || execTime.TotalMilliseconds > timeout)
                _logger.LogWarning($"Rest执行耗时({execTime.TotalMilliseconds.ToString()})毫秒 -- {restUrl}");
        }
        #endregion

        #region Error
        public static void LogError(string error)
        {
            _logger.LogError(error);
        }
        public static void LogError(string error, string detail)
        {
            _logger.LogError($"{error} -- {detail}");
        }
        public static void LogError(Exception ex)
        {
            _logger.LogError($"{ex.Message}\r\n{ex.StackTrace}");
        }
        public static void LogError(string error, Exception ex)
        {
            _logger.LogError($"{error} -- {ex.Message}\r\n{ex.StackTrace}");
        }
        public static void LogErrorForTransExec(string transName, Exception ex)
        {
            _logger.LogError($"交易执行失败 -- {transName} -- {ex.Message}\r\n{ex.StackTrace}");
        }
        public static void LogErrorForSqlExec(Exception ex)
        {
            _logger.LogError($"Sql执行失败 -- {ex.Message}\r\n{ex.StackTrace}");
        }
        public static void LogErrorForSqlExec(Exception ex, string originalSql)
        {
            _logger.LogError($"Sql执行失败 -- {ex.Message}\r\n   (原始Sql) {originalSql.Trim()}");
        }
        public static void LogErrorForSqlExec(CommandErrorEventData eventData, string originalSql)
        {
            _logger.LogError($"Sql执行失败 -- {eventData.Exception.Message}\r\n   (含{eventData.Command.Parameters.Count}个参数) {eventData.Command.CommandText.Trim()}\r\n   (原始Sql) {originalSql.Trim()}");
        }
        public static void LogErrorForRestExec(string restUrl, Exception ex)
        {
            _logger.LogError($"Rest执行失败 -- {restUrl} -- {ex.Message}\r\n{ex.StackTrace}");
        }
        public static void LogErrorForSoapExec(string soapUrl, Exception ex)
        {
            _logger.LogError($"Soap执行失败 -- {soapUrl} -- {ex.Message}\r\n{ex.StackTrace}");
        }
        #endregion
    }
}
